const userService = require("../service/user.service")
const { NAME_OR_PWD_IS_REQUIRED, NAME_IS_ALREADY_EXISTS, NAME_IS_NOT_EXISTS, PASSWORD_IS_ERROR, UNAUTHORIZED } = require("../config/error")
const md5Encryption = require("../utils/md5-encryption")
const jwt = require('jsonwebtoken')
const { PUBLIC_KEY } = require("../config/serect")

// 验证用户登录中间件
const verifyLogin = async (ctx, next) => {
  const { name, password } = ctx.request.body

  // 1.用户名或密码为空
  if (!name || !password) {
    return ctx.app.emit('error', NAME_OR_PWD_IS_REQUIRED, ctx)
  }

  // 2.用户不存在数据库中
  const users = await userService.findUserByName(name)
  if (!users[0]) {
    return ctx.app.emit('error', NAME_IS_NOT_EXISTS, ctx)
  }

  // 3.密码不正确
  if (users[0].password !== md5Encryption(password)) {
    return ctx.app.emit('error', PASSWORD_IS_ERROR, ctx)
  }

  // 将user保存在ctx中共享
  ctx.user = users[0]

  await next()
}

// 验证token令牌中间件
const verifyAuth = async (ctx, next) => {
  // 1.获取token
  const authorization = ctx.header.authorization
  if (!authorization) {
    return ctx.app.emit('error', UNAUTHORIZED, ctx)
  }
  const token = authorization.replace('Bearer ', '')

  // 2.使用公钥验证token
  try {
    const jwtPayload = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ['RS256']
    })

    // 3.将token中保存的用户信息通过ctx共享给所有中间件
    ctx.user = jwtPayload
    await next()
  } catch (error) {
    ctx.app.emit('error', UNAUTHORIZED, ctx)
  }
}

module.exports = {
  verifyLogin,
  verifyAuth
}